Skip to content

Install the pinned reachability engine in the Docker image - #345

Open
lelia wants to merge 1 commit into
mainfrom
lelia/ce-431-coana-pin
Open

Install the pinned reachability engine in the Docker image#345
lelia wants to merge 1 commit into
mainfrom
lelia/ce-431-coana-pin

Conversation

@lelia

@lelia lelia commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Problem

Dockerfile installed @coana-tech/cli unpinned, while the launcher asks npx for the version in DEFAULT_COANA_CLI_VERSION. npx reuses the image's global install only when the versions match; on a mismatch it downloads the engine again on every scan.

Measured in the published image:

Requested version Launcher npm cache delta
matches the global install 3s 0 MB
mismatched 9s +119 MB

The two agreed only because release rebuilds happened to follow the pin bumps. Nothing enforced it, and the failure mode is silent — no error, no test failure, just slower scans and extra egress.

Change

  • The Dockerfile reads the pinned version out of reachability.py and installs exactly that, failing the build if the value cannot be read. The pin stays bumped in one place, so the image and the runtime cannot drift.
  • The coana install moves out of the toolchain RUN. A pin bump now rebuilds a 353 MB layer instead of the 2.3 GB combined layer.
  • Marking a release stable builds that version from its own tag. The image installs socketsecurity==inputs.version from PyPI, so building from the default branch paired an old wheel with a newer build recipe and pin.
  • tests/unit/test_dockerfile_coana_pin.py runs the Dockerfile's own extraction expression against the real source and rejects an unpinned install. Dockerfile was added to the unit-test path filter so the guard runs on Dockerfile-only changes.

Verification

  • Full image build: baked engine, runtime pin and source all report 15.10.36; socketcli --help and coana-cli both work.
  • Building against a source file with the constant renamed aborts with Could not read DEFAULT_COANA_CLI_VERSION from reachability.py rather than silently installing unpinned.
  • After the change npx resolves without downloading — metadata only, no cache growth.
  • Both guards fail on their respective mutations and pass when reverted.
  • 425 unit tests pass, 2 pre-existing skips. The extraction expression was checked under both BSD and busybox sed.

e2e-reachability needs to run here — this changes how the engine is installed, so it is the meaningful gate.

Not included

socket npm is still installed unpinned and the npm cache is still shipped in the image. Both are tracked separately.


Refs: CE-431


Note

Medium Risk
Changes how the published Docker image installs the reachability engine and how stable releases are checked out; misconfiguration could cause failed builds or resumed per-scan downloads, but runtime scan logic is unchanged.

Overview
Fixes Docker scans re-downloading the reachability engine when the image’s global @coana-tech/cli didn’t match what the CLI requests via npx @coana-tech/cli@DEFAULT_COANA_CLI_VERSION.

The Dockerfile now copies reachability.py, extracts the pin with sed, and runs npm install @coana-tech/cli@<that version> (build fails if extraction fails). The Coana install is split into its own layer so pin bumps don’t rebuild the larger toolchain step. Mark release as stable checks out ref: v${{ inputs.version }} so stable images are built from the tagged release’s Dockerfile/pin, not main paired with an older PyPI wheel.

CI adds Dockerfile to the unit-test path filter and new test_dockerfile_coana_pin.py guards the sed expression and rejects unpinned Coana npm install lines. Release is bumped to 2.7.2 with changelog notes.

Reviewed by Cursor Bugbot for commit 21a802d. Configure here.

The image installed @coana-tech/cli unpinned while the launcher asks npx for
DEFAULT_COANA_CLI_VERSION. npx reuses the global install only when the versions
match, so once the two diverged every scan re-downloaded the engine (~119 MB)
and the launcher took roughly three times as long, silently. The Dockerfile now
reads the pinned version out of reachability.py, so the image and the runtime
cannot drift and the pin stays bumped in exactly one place.

Splitting the coana install out of the toolchain RUN keeps a pin bump to a
353 MB layer rather than rebuilding the 2.3 GB combined layer.

Marking a release stable now builds that version from its own tag, so an older
wheel is no longer paired with the default branch's build recipe and pin.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@lelia
lelia requested a review from a team as a code owner September 7, 2026 18:11
@lelia
lelia deployed to socket-firewall September 7, 2026 18:11 — with GitHub Actions Active
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant